import { PayloadAction, createSlice } from "@reduxjs/toolkit"
import { parse, format } from "date-fns"

type CurrentClient = {
  name: string
  id: string
}

type Services = {
  name: string
  id: string
}

export type ClientState = {
  name: string
  id: string
  services: Services[]
}

type User = {
  id: string
  first_name: string
  middle_name: string
  last_name: string
  status: string
  phone_number: string
  email: string
  latest_appointment: string
  billing_type: string
}

type ServiceObject = {
  id?: string
  provider?: string
  code?: string
  service?: string
  fee?: number
  time?: number
}
interface ServicesState {
  id?: string
  client?: string
  service?: ServiceObject
  fees: string
  is_default: true
}
interface AppointmentState {
  room?: string
  roomId?: string
  roomCost?: string
  status?: number
  error?: string
  clients: User[]
  endTime?: string
  loading?: boolean
  startTime?: string
  bookingId?: string
  datePassed?: boolean
  healthCheckBox?: boolean
  weeklyCheckbox?: boolean
  appointmentDetails?: {}
  dateCheckBox?: boolean
  meetCheckBox?: boolean
  zoomCheckBox?: boolean
  etheraRooms: object[]
  selectedDates?: {}
  selectedDatesArray?: any[]
  appointmentLoader?: boolean
  bookingEndTime?: string
  bookingStartTime?: string
  weeklyRepeatGap?: string
  appointmentDate?: string
  number_of_weeks?: number
  OtherLocations: object[]
  services: ServicesState[]
  EtheraLocations: object[]
  allSelectedClients?: ClientState[]
  appointmentLocation?: string
  appointmentLocationId?: string
  appointmentLocationType?: string
  selectedClient?: CurrentClient
}

const initialState: AppointmentState = {
  room: "",
  roomId: "",
  roomCost: "0:00",
  status: null,
  error: "",
  endTime: "10:00 AM",
  clients: [],
  services: [],
  bookingId: "",
  startTime: "09:00 AM",
  loading: false,
  etheraRooms: [],
  datePassed: false,
  appointmentLoader: false,
  selectedDates: {},
  OtherLocations: [],
  selectedDatesArray: null,
  bookingEndTime: "10:00 AM",
  bookingStartTime: "09:00 AM",
  weeklyCheckbox: false,
  dateCheckBox: false,
  weeklyRepeatGap: "",
  EtheraLocations: [],
  selectedClient: null,
  appointmentDate: "",
  appointmentDetails: {},
  allSelectedClients: [],
  number_of_weeks: null,
  appointmentLocation: "",
  appointmentLocationId: "",
  appointmentLocationType: "",
}

const CreateAppointmentSlice = createSlice({
  name: "createAppointment",
  initialState,

  reducers: {
    setRoom: (state, action) => {
      state.room = action?.payload?.room?.label
      state.roomId = action?.payload?.room?.value
    },
    setStartTime: (state, action) => {
      state.startTime = action?.payload?.startTime
    },
    setBookingStartTime: (state, action) => {
      state.bookingStartTime = action?.payload?.bookingStartTime
      state.startTime = action?.payload?.bookingStartTime
    },
    setEndTime: (state, action) => {
      state.endTime = action?.payload?.endTime
    },
    setBookingEndTime: (state, action) => {
      state.bookingEndTime = action?.payload?.bookingEndTime
      state.endTime = action?.payload?.bookingEndTime
    },
    setAppointmentLocation: (state, action) => {
      state.appointmentLocation = action?.payload?.name
      state.appointmentLocationType = action?.payload?.type
      state.appointmentLocationId = action?.payload?.id
    },
    setNumberOfWeeks: (state, action) => {
      state.number_of_weeks = action?.payload?.number_of_weeks
    },
    setWeeklyRepeatGap: (state, action) => {
      state.weeklyRepeatGap = action?.payload?.weeklyRepeatGap
    },
    setAppointmentDate: (state, action) => {
      state.appointmentDate = action?.payload?.appointmentDate
    },
    setSelectedDates: (state, action) => {
      const updatedDates = { ...state.selectedDates }
      if (updatedDates[action?.payload.date?.dateString]) {
        delete updatedDates[action?.payload?.date?.dateString]
      } else {
        updatedDates[action?.payload.date.dateString] = {
          color: "#8ca765",
          selected: true,
          selectedColor: "#E89234",
        }
      }

      ;(state.selectedDates = updatedDates), (state.selectedDatesArray = Object.keys(updatedDates))
    },
    populateSelectedDates: (state, action) => {
      let updatedDates = {}
      action?.payload.map((date) => {
        try {
          // Parse the input date string
          const inputDate = parse(date, "yyyy-MM-dd'T'HH:mm:ss", new Date())
          // Format the output date string as "yyyy-MM-dd"
          const outputDateString = format(inputDate, "yyyy-MM-dd")
          updatedDates[outputDateString] = {
            color: "#8ca765",
            selected: true,
            selectedColor: "#E89234",
          }
          ;(state.selectedDates = updatedDates),
            (state.selectedDatesArray = Object.keys(updatedDates))
        } catch (error) {
          console.error("Error processing date:", error)
        }
      })
    },
    setSelectedClients: (state, action) => {
      state.selectedClient = action?.payload
      const updatedSelectedClient = [...state.allSelectedClients]
      updatedSelectedClient.push(action.payload)
      state.allSelectedClients = updatedSelectedClient
    },
    removeSelectedClients: (state, action) => {
      state.allSelectedClients = action?.payload
    },
    removeServices: (state, action) => {
      state.allSelectedClients = action?.payload
    },
    addServices: (state, action) => {
      const updatedArray = state?.allSelectedClients?.map((item) => {
        //Filtering the item to whom service should be
        if (item.id === action?.payload?.id) {
          const existingServices = Array.isArray(item?.services) ? item.services : []
          if (!existingServices.some((service) => service.id === action?.payload?.services?.id)) {
            return {
              ...item,
              services: [...existingServices, action?.payload?.services],
            }
          }
        }
        return item
      })
      //@ts-ignore
      state.allSelectedClients = updatedArray
    },
    setClients: (state, action) => {
      state.clients = action?.payload
    },
    setServices: (state, action) => {
      state.services = action?.payload
    },
    setEtheraLocations: (state, action) => {
      state.EtheraLocations = action?.payload
    },
    setOtherLocations: (state, action) => {
      state.OtherLocations = action?.payload
    },
    setEtheraRooms: (state, action) => {
      state.etheraRooms = action?.payload
    },
    setAppointmentLoader: (state, action) => {
      state.appointmentLoader = action?.payload
    },
    resetAppointmentLocationScreen: (state) => {
      state.appointmentLocationType = ""
      state.appointmentLocation = ""
      state.bookingStartTime = "09:00 AM"
      state.appointmentDate = ""
      state.healthCheckBox = false
      state.meetCheckBox = false
      state.zoomCheckBox = false
      state.number_of_weeks = null
      state.allSelectedClients = []
      state.weeklyRepeatGap = ""
      state.bookingEndTime = "10:00 AM"
      state.startTime = "09:00 AM"
      state.endTime = "10:00 AM"
      state.services = []
      state.clients = []
      state.room = ""
      state.roomId = ""
      state.roomCost = "0:00"
      state.selectedDates = {}
      state.selectedDatesArray = []
      state.weeklyCheckbox = false
      state.dateCheckBox = false
    },
    setBookingId: (state, action) => {
      state.bookingId = action?.payload?.bookingId
    },
    setError: (state, action) => {
      state.error = action?.payload
    },
    setWeeklyCheckBox: (state, action) => {
      state.weeklyCheckbox = action?.payload
      //here if week check box is marked false both weeklyRepeatGap & number_of_weeks will be reset
      if (action?.payload === false) {
        state.weeklyRepeatGap = null
        state.number_of_weeks = null
      } else {
        state.dateCheckBox = false
        state.selectedDates = {}
      }
    },
    setDateCheckBox: (state, action) => {
      state.dateCheckBox = action?.payload
      //here if week check box is marked false both weeklyRepeatGap & number_of_weeks will be reset
      if (action?.payload === false) {
        state.selectedDates = {}
        state.selectedDatesArray = null
      } else {
        state.weeklyRepeatGap = null
        state.number_of_weeks = null
      }
    },
    setHealthCheckBox: (state, action) => {
      state.healthCheckBox = action?.payload
    },
    setMeetCheckBox: (state, action) => {
      state.meetCheckBox = action?.payload
    },
    setZoomCheckBox: (state, action) => {
      state.zoomCheckBox = action?.payload
    },
    //This is boolean True in case start-date is true and false if date is passed away
    editDetails: (state, action) => {
      state.datePassed = action?.payload
    },
    setAppointmentStatus: (state, action) => {
      state.status = action?.payload
    },
    setRoomCost: (state, action) => {
      state.roomCost = action?.payload
    },
    //this state holds complete object fetched in getAppointmentDetail to compare with new values
    setAppointmentDetails: (state, action) => {
      state.appointmentDetails = action?.payload
    },
  },
})

export default CreateAppointmentSlice.reducer
export const {
  setRoom,
  setError,
  setEndTime,
  setClients,
  setRoomCost,
  addServices,
  editDetails,
  setServices,
  setStartTime,
  setBookingId,
  setEtheraRooms,
  removeServices,
  setSelectedDates,
  setAppointmentLoader,
  setDateCheckBox,
  setZoomCheckBox,
  setHealthCheckBox,
  setMeetCheckBox,
  setWeeklyCheckBox,
  setOtherLocations,
  setAppointmentDate,
  setBookingEndTime,
  setBookingStartTime,
  setEtheraLocations,
  setSelectedClients,
  setWeeklyRepeatGap,
  setNumberOfWeeks,
  setAppointmentStatus,
  removeSelectedClients,
  populateSelectedDates,
  setAppointmentLocation,
  setAppointmentDetails,
  resetAppointmentLocationScreen,
} = CreateAppointmentSlice.actions
